package com.iknight.mgr.core.utils;

import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;

import java.io.*;
import java.lang.reflect.Field;
import java.util.Map;

public class IkgDom4jUtils {
    /**
     * @param parent
     * @param childName
     * @param childlValue
     * @return
     */
    public static Element addChild(Element parent, String childName, String childlValue) {
        Element child = parent.addElement(childName);
        child.setText(IkgStringUtils.ObjectToString(childlValue));
        return child;
    }

    /**
     * @param document
     * @param charset
     * @return
     */
    public static String documentToString(Document document, String charset) {
        StringWriter stringWriter = new StringWriter();
        OutputFormat format = OutputFormat.createPrettyPrint();//获得格式化输出流
        format.setEncoding(charset);//设置字符集,默觉得UTF-8
        XMLWriter xmlWriter = new XMLWriter(stringWriter, format);//写文件流
        try {
            xmlWriter.write(document);
            xmlWriter.flush();
            xmlWriter.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return stringWriter.toString();
    }

    /**
     * @param mapperClass Mapper类
     * @param modelClass  实体类
     * @param tableName   表名
     * @param filePath    文件存放路径
     */
    public static void createMapperDocument(Class mapperClass, Class modelClass, String tableName, String filePath) {

        Field[] fields = modelClass.getDeclaredFields();

        Document document = DocumentHelper.createDocument();
        document.addDocType("mapper", "-//mybatis.org//DTD Mapper 3.0//EN", "http://mybatis.org/dtd/mybatis-3-mapper.dtd");
        Element root = document.addElement("mapper");
        root.addAttribute("namespace", mapperClass.getName());
        Element sql = root.addElement("sql");
        sql.addAttribute("id", "BaseColumns");
        for (Field field : fields) {
            sql.addText(field.getName()).addText(",");
        }

        Element insert = root.addElement("insert");
        insert.addAttribute("id", "insert");
        insert.addAttribute("parameterType", modelClass.getName());

        StringBuffer insertBuffer = new StringBuffer(100);
        insertBuffer.append("insert into ").append(tableName).append(" ");
        insert.setText(insertBuffer.toString());
        Element trimInsertEle = insert.addElement("trim");
        trimInsertEle.addAttribute("prefix", "(");
        trimInsertEle.addAttribute("suffix", ")");
        trimInsertEle.addAttribute("suffixOverrides", ",");

        for (Field field : fields) {
            trimInsertEle.addElement("if")
                    .addAttribute("test", field.getName() + "!=null and " + field.getName() + "!=''")
                    .setText(field.getName() + ",");
        }
        Element trimInsertAfter = insert.addElement("trim");
        trimInsertAfter.addAttribute("prefix", "values (");
        trimInsertAfter.addAttribute("suffix", ")");
        trimInsertAfter.addAttribute("suffixOverrides", ",");
        for (Field field : fields) {
            trimInsertAfter.addElement("if")
                    .addAttribute("test", field.getName() + "!=null and " + field.getName() + "!=''")
                    .setText("#{" + field.getName() + "},");
        }

        Element delete = root.addElement("delete");
        delete.addAttribute("id", "delete");
        delete.addAttribute("parameterType", String.class.getName());
        delete.setText("delete from " + tableName + " where ");

        Element update = root.addElement("update");
        update.addAttribute("id", "update");
        update.addAttribute("parameterType", modelClass.getName());
        update.addText("update ").addText(tableName);
        Element updateBeforeEle = update.addElement("trim");
        updateBeforeEle.addAttribute("prefix", "set");
        updateBeforeEle.addAttribute("suffixOverrides", ",");
        for (Field field : fields) {
            updateBeforeEle.addElement("if")
                    .addAttribute("test", field.getName() + "!=null and " + field.getName() + "!=''")
                    .setText(field.getName() + "=#{" + field.getName() + "},");
        }

        Element selectOne = root.addElement("select");
        selectOne.addAttribute("id", "selectOne");
        selectOne.addAttribute("parameterType", String.class.getName());
        selectOne.addText("select");
        selectOne.addElement("include").addAttribute("refid", "BaseColumns");
        selectOne.addText(" from ").addText(tableName);

        Element selectByCond = root.addElement("select");
        selectByCond.addAttribute("id", "selectByCond");
        selectByCond.addAttribute("parameterType", Map.class.getName());
        selectByCond.addAttribute("resultType", modelClass.getName());
        selectByCond.addText("select");
        selectByCond.addElement("include").addAttribute("refid", "BaseColumns");
        selectByCond.addText(" from ").addText(tableName);
        Element trimCond = selectByCond.addElement("trim");
        trimCond.addAttribute("prefix", "where");
        trimCond.addAttribute("prefixOverrides", "and|or");
        for (Field field : fields) {
            trimCond.addElement("if")
                    .addAttribute("test", field.getName() + "!=null and " + field.getName() + "!=''")
                    .addText("and ")
                    .addText(field.getName())
                    .addText("=#{" + field.getName() + "}");
        }

        OutputFormat format = OutputFormat.createPrettyPrint();
        try {
            XMLWriter xmlWriter = new XMLWriter(new FileOutputStream(filePath + File.separator + mapperClass.getSimpleName() + ".xml"), format);
            xmlWriter.write(document);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 创建html模板文件
     *
     * @param filePath
     * @param fileName
     */
    public static void createTemplateDocument(String filePath, String fileName) {
        Document document = DocumentHelper.createDocument();
        Element htmlEle = document.addElement("html");
        Element rootGridEle = htmlEle.addElement("div");
        rootGridEle.addAttribute("class", "container-fluid");
        Element searchAreaEle = rootGridEle.addElement("div");
        searchAreaEle.addAttribute("class", "row ikg-row");
        searchAreaEle.addComment("查询区域");
        Element searchAreaPanelBodyEle = searchAreaEle.addElement("div")
                .addAttribute("class", "panel panel-default ikg-panel")
                .addElement("div")
                .addAttribute("class", "panel-body")
                .addComment("详细设置");
        Element inputGroup = searchAreaPanelBodyEle.addElement("div")
                .addAttribute("class", "col-lg-4")
                .addElement("div")
                .addAttribute("class", "input-group");
        inputGroup.addElement("label")
                .addAttribute("class", "input-group-addon ikg-font-12")
                .setText("[元件标题]");
        inputGroup.addElement("input")
                .addAttribute("type", "text")
                .addAttribute("class", "form-control")
                .addAttribute("data-bind", "");
        Element searchBtnAreaEle = searchAreaPanelBodyEle.addElement("div")
                .addAttribute("class", "col-lg-4");
        Element searchBtn = searchBtnAreaEle.addElement("button")
                .addAttribute("class", "btn btn-success btn-sm")
                .addAttribute("data-bind", "click:fnSearch");
        searchBtn.addElement("i")
                .addAttribute("class", "fa fa-search fa-lg");
        searchBtn.addElement("span")
                .addAttribute("class", "hidden-xs hidden-sm")
                .setText("查询");
        Element resetBtn = searchBtnAreaEle.addElement("button")
                .addAttribute("class", "btn btn-success btn-sm")
                .addAttribute("data-bind", "click:fnReset");
        resetBtn.addElement("i")
                .addAttribute("class", "fa fa-repeat fa-lg");
        resetBtn.addElement("span")
                .addAttribute("class", "hidden-xs hidden-sm")
                .setText("重置");

        Element toolbarAreaEle = rootGridEle.addElement("div").addAttribute("class", "row ikg-row");
        toolbarAreaEle.addComment("工具栏区域");
        Element toolbarEle = toolbarAreaEle.addElement("div")
                .addAttribute("class", "col-sm-12 ikg-col")
                .addElement("div")
                .addAttribute("id", "toolbar")
                .addAttribute("class", "btn-group");

        Element addEle = toolbarEle.addElement("button")
                .addAttribute("class", "btn btn-success btn-sm")
                .addAttribute("data-bind", "click:fnAdd");
        addEle.addElement("i")
                .addAttribute("class", "fa fa-plus fa-lg")
                .addAttribute("aria-hidden", "true");
        addEle.addElement("span")
                .addAttribute("class", "hidden-sm hidden-xs")
                .setText(" 新增");

        Element deleteEle = toolbarEle.addElement("button")
                .addAttribute("class", "btn btn-success btn-sm")
                .addAttribute("data-bind", "click:fnRemove");
        deleteEle.addElement("i")
                .addAttribute("class", "fa fa-trash fa-lg")
                .addAttribute("aria-hidden", "true");
        deleteEle.addElement("span")
                .addAttribute("class", "hidden-sm hidden-xs")
                .setText(" 删除");

        Element updateEle = toolbarEle.addElement("button")
                .addAttribute("class", "btn btn-success btn-sm")
                .addAttribute("data-bind", "click:fnEdit");
        updateEle.addElement("i")
                .addAttribute("class", "fa fa-pencil-square-o fa-lg")
                .addAttribute("aria-hidden", "true");
        updateEle.addElement("span")
                .addAttribute("class", "hidden-sm hidden-xs")
                .setText(" 编辑");

        Element queryle = toolbarEle.addElement("button")
                .addAttribute("class", "btn btn-success btn-sm")
                .addAttribute("data-bind", "click:fnMove");
        queryle.addElement("i")
                .addAttribute("class", "fa fa-file-text fa-lg")
                .addAttribute("aria-hidden", "true");
        queryle.addElement("span")
                .addAttribute("class", "hidden-sm hidden-xs")
                .setText(" 查看");

        Element gridAreaEle = rootGridEle.addElement("div");
        gridAreaEle.addAttribute("class", "row ikg-row table-responsive").addComment("列表区域");
        gridAreaEle.addElement("div")
                .addAttribute("class", "col-sm-12 ikg-col")
                .addElement("table")
                .addAttribute("data-bind", "tableView:{tableViewModel}")
                .addAttribute("class", "table text-nowrap");

        Element rootDetailsEle = htmlEle.addElement("div");
        rootDetailsEle.addAttribute("id", "DetailsDlg")
                .addAttribute("class", "modal hide")
                .addAttribute("tabindex", "-1")
                .addAttribute("role", "dialog")
                .addAttribute("data-bind", "template:{name:'[]',data:[]},ikgModal:{ backdrop: 'static', keyboard: false, show: []}");

        Element scriptEle = htmlEle.addElement("script");
        scriptEle.addAttribute("id", "[]");
        scriptEle.addAttribute("type", "text/html");
        scriptEle.addComment("详情表单模板");

        Element scriptModelEle = scriptEle.addElement("div");
        scriptModelEle.addAttribute("class", "modal-dialog")
                .addAttribute("style", "width:640px")
                .addAttribute("role", "document");

        Element scriptModelContentEle = scriptModelEle.addElement("div");
        scriptModelContentEle.addAttribute("class", "modal-content");

        Element header = scriptModelContentEle.addElement("div");
        header.addAttribute("class", "modal-header ikg-modal-header");
        header.addComment("Model Header");
        header.addElement("button")
                .addAttribute("type", "button")
                .addAttribute("class", "close ikg-close")
                .addAttribute("data-bind", "click: close")
                .setText("&times;");
        header.addElement("span")
                .addAttribute("class", "modal-title ikg-modal-title")
                .addAttribute("data-bind", "text:title");

        Element body = scriptModelContentEle.addElement("div");
        body.addAttribute("class", "modal-body");
        body.addComment("Model Body");
        Element form = body.addElement("form");
        form.addComment("Model Form");
        form.addAttribute("id", "detailsForm");
        form.addAttribute("autocomplete", "off");
        form.addAttribute("class", "form-horizontal");

        Element formEle = form.addElement("div").addAttribute("class", "form-group");
        formEle.addElement("label")
                .addAttribute("class", "col-sm-3 control-label")
                .addAttribute("for", "")
                .setText("元件标题:");
        formEle.addElement("div")
                .addAttribute("class", "col-sm-8")
                .addComment("绑定元件，如input")
                .addElement("input")
                .addAttribute("type", "text")
                .addAttribute("class", "form-control")
                .addAttribute("name", "")
                .addAttribute("id", "")
                .addAttribute("data-bind", "value:{ko_value}");

        Element foot = scriptModelContentEle.addElement("div");
        foot.addAttribute("class", "modal-footer");
        Element saveBtnEle = foot.addElement("button");

        saveBtnEle.addAttribute("type", "button")
                .addAttribute("class", "btn btn-success ikg-btn-12")
                .addAttribute("data-bind", "click:save");
        saveBtnEle.addElement("i").addAttribute("class", "fa fa-save fa-lg");
        saveBtnEle.addElement("span").setText(" 保存");

        Element cancelBtnEle = foot.addElement("button")
                .addAttribute("type", "button")
                .addAttribute("class", "btn btn-default ikg-btn-12")
                .addAttribute("data-bind", "click:close");
        cancelBtnEle.addElement("i")
                .addAttribute("class", "fa fa-close fa-lg");
        cancelBtnEle.addElement("span").setText(" 关闭");

        OutputFormat format = OutputFormat.createPrettyPrint();
        try {
            XMLWriter xmlWriter = new XMLWriter(new FileOutputStream(filePath + File.separator + fileName), format);
            xmlWriter.write(document);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
